﻿using System;
using System.Collections.Generic;
using System.Linq;

// --- 使用别名解决命名空间冲突 ---
using WinForms = System.Windows.Forms;
using Drawing = System.Drawing;

// Revit API 命名空间
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Analysis;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.Attributes;

namespace RevitApiExample1 // 请确保你的项目使用正确的命名空间
{
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    public class ChangeSpaceTypeCommand : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Document doc = uidoc.Document;

            // --- 1. 用户交互 - 选择空间 ---
            Reference pickedRef = null;
            Space selectedSpace = null;
            try
            {
                ISelectionFilter spaceFilter = new SpaceSelectionFilter();
                pickedRef = uidoc.Selection.PickObject(ObjectType.Element, spaceFilter, "请选择一个要更改类型的空间 (Select a Space to change its type)");
                Element selectedElem = doc.GetElement(pickedRef);
                selectedSpace = selectedElem as Space;

                if (selectedSpace == null)
                {
                    message = "选择的图元不是有效的空间。";
                    return Result.Failed;
                }
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException)
            {
                return Result.Cancelled;
            }
            catch (Exception ex)
            {
                message = $"选择空间时出错: {ex.Message}";
                return Result.Failed;
            }

            // --- 2. 数据准备 - 获取可用的空间类型 ---
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            IList<HVACLoadSpaceType> availableSpaceTypes = collector
                .OfClass(typeof(HVACLoadSpaceType))
                .Cast<HVACLoadSpaceType>()
                .OrderBy(st => st.Name)
                .ToList();

            if (availableSpaceTypes.Count == 0)
            {
                message = "项目中未定义任何空间类型 (HVACLoadSpaceType)。";
                return Result.Failed;
            }

            // --- 3. 用户交互 - 选择新的空间类型 ---
            ElementId newSpaceTypeId = ElementId.InvalidElementId;
            // 注意这里的 using 仍然有效，因为 SelectSpaceTypeForm 继承自 WinForms.Form (它实现了 IDisposable)
            using (SelectSpaceTypeForm form = new SelectSpaceTypeForm(availableSpaceTypes))
            {
                // 使用别名访问 DialogResult
                if (form.ShowDialog() == WinForms.DialogResult.OK)
                {
                    newSpaceTypeId = form.SelectedSpaceTypeId;
                }
                else
                {
                    return Result.Cancelled;
                }
            }

            if (newSpaceTypeId == null || newSpaceTypeId == ElementId.InvalidElementId)
            {
                message = "未能获取有效的空间类型选择。";
                return Result.Failed;
            }

            if (selectedSpace.GetTypeId() == newSpaceTypeId)
            {
                // TaskDialog 是 Revit API 的，不需要别名
                TaskDialog.Show("提示", "所选空间已经是目标类型。无需更改。");
                return Result.Succeeded;
            }

            // --- 4. 执行操作 - 更改空间类型 ---
            try
            {
                using (Transaction tx = new Transaction(doc, "更改空间类型"))
                {
                    tx.Start();
                    selectedSpace.SpaceTypeId = newSpaceTypeId;
                    tx.Commit();
                }
                TaskDialog.Show("成功", $"空间 '{selectedSpace.Name}' (ID: {selectedSpace.Id}) 的类型已更改。");
                return Result.Succeeded;
            }
            catch (Exception ex)
            {
                message = $"更改空间类型时发生错误: {ex.Message}";
                return Result.Failed;
            }
        }
    }

    /// <summary>
    /// 选择过滤器，仅允许选择 Space 图元
    /// </summary>
    public class SpaceSelectionFilter : ISelectionFilter
    {
        public bool AllowElement(Element elem)
        {
            return elem is Space;
        }

        public bool AllowReference(Reference reference, XYZ position)
        {
            return false;
        }
    }

    /// <summary>
    /// 一个简单的 Windows Form 用于选择空间类型
    /// 继承时明确使用别名 WinForms.Form
    /// </summary>
    public class SelectSpaceTypeForm : WinForms.Form // 明确继承自 WinForms.Form
    {
        // 控件类型前使用别名
        private WinForms.ComboBox comboBoxSpaceTypes;
        private WinForms.Button buttonOk;
        private WinForms.Button buttonCancel;
        private WinForms.Label labelInstruction; // 明确使用 WinForms.Label
        private Dictionary<string, ElementId> _spaceTypeMap;

        public ElementId SelectedSpaceTypeId { get; private set; } = ElementId.InvalidElementId;

        public SelectSpaceTypeForm(IList<HVACLoadSpaceType> spaceTypes)
        {
            InitializeComponent();
            _spaceTypeMap = new Dictionary<string, ElementId>();

            foreach (var type in spaceTypes)
            {
                if (type != null && !string.IsNullOrEmpty(type.Name))
                {
                    string displayName = $"{type.Name} (ID: {type.Id.IntegerValue})";
                    if (!_spaceTypeMap.ContainsKey(displayName))
                    {
                        comboBoxSpaceTypes.Items.Add(displayName);
                        _spaceTypeMap.Add(displayName, type.Id);
                    }
                }
            }

            if (comboBoxSpaceTypes.Items.Count > 0)
            {
                comboBoxSpaceTypes.SelectedIndex = 0;
            }
            else
            {
                buttonOk.Enabled = false;
            }
        }

        private void InitializeComponent()
        {
            // 实例化控件时使用别名
            this.comboBoxSpaceTypes = new WinForms.ComboBox();
            this.buttonOk = new WinForms.Button();
            this.buttonCancel = new WinForms.Button();
            this.labelInstruction = new WinForms.Label(); // 明确使用 WinForms.Label
            this.SuspendLayout();
            //
            // labelInstruction
            //
            this.labelInstruction.AutoSize = true;
            // Point 和 Size 来自 System.Drawing，使用 Drawing 别名
            this.labelInstruction.Location = new Drawing.Point(12, 15);
            this.labelInstruction.Name = "labelInstruction";
            this.labelInstruction.Size = new Drawing.Size(149, 13);
            this.labelInstruction.TabIndex = 0;
            this.labelInstruction.Text = "请选择新的空间类型:";
            //
            // comboBoxSpaceTypes
            //
            // ComboBoxStyle 使用 WinForms 别名
            this.comboBoxSpaceTypes.DropDownStyle = WinForms.ComboBoxStyle.DropDownList;
            this.comboBoxSpaceTypes.FormattingEnabled = true;
            this.comboBoxSpaceTypes.Location = new Drawing.Point(15, 35);
            this.comboBoxSpaceTypes.Name = "comboBoxSpaceTypes";
            this.comboBoxSpaceTypes.Size = new Drawing.Size(257, 21);
            this.comboBoxSpaceTypes.TabIndex = 1;
            //
            // buttonOk
            //
            // DialogResult 使用 WinForms 别名
            this.buttonOk.DialogResult = WinForms.DialogResult.OK;
            this.buttonOk.Location = new Drawing.Point(116, 70);
            this.buttonOk.Name = "buttonOk";
            this.buttonOk.Size = new Drawing.Size(75, 23);
            this.buttonOk.TabIndex = 2;
            this.buttonOk.Text = "确定";
            this.buttonOk.UseVisualStyleBackColor = true;
            // EventHandler 使用 System (不需要别名，因为它不冲突)
            this.buttonOk.Click += new System.EventHandler(this.ButtonOk_Click);
            //
            // buttonCancel
            //
            this.buttonCancel.DialogResult = WinForms.DialogResult.Cancel;
            this.buttonCancel.Location = new Drawing.Point(197, 70);
            this.buttonCancel.Name = "buttonCancel";
            this.buttonCancel.Size = new Drawing.Size(75, 23);
            this.buttonCancel.TabIndex = 3;
            this.buttonCancel.Text = "取消";
            this.buttonCancel.UseVisualStyleBackColor = true;
            //
            // SelectSpaceTypeForm
            //
            this.AcceptButton = this.buttonOk;
            this.CancelButton = this.buttonCancel;
            // ClientSize 使用 Drawing.Size
            this.ClientSize = new Drawing.Size(284, 111);
            this.Controls.Add(this.labelInstruction);
            this.Controls.Add(this.comboBoxSpaceTypes);
            this.Controls.Add(this.buttonOk);
            this.Controls.Add(this.buttonCancel);
            // FormBorderStyle 使用 WinForms 别名
            this.FormBorderStyle = WinForms.FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "SelectSpaceTypeForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            // FormStartPosition 使用 WinForms 别名
            this.StartPosition = WinForms.FormStartPosition.CenterParent;
            this.Text = "选择空间类型";
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        // OK 按钮点击事件处理
        private void ButtonOk_Click(object sender, EventArgs e)
        {
            if (comboBoxSpaceTypes.SelectedItem != null)
            {
                string selectedDisplayName = comboBoxSpaceTypes.SelectedItem.ToString();
                if (_spaceTypeMap.ContainsKey(selectedDisplayName))
                {
                    this.SelectedSpaceTypeId = _spaceTypeMap[selectedDisplayName];
                    this.DialogResult = WinForms.DialogResult.OK; // 使用别名
                }
                else
                {
                    // MessageBox, MessageBoxButtons, MessageBoxIcon 使用 WinForms 别名
                    WinForms.MessageBox.Show("内部错误：无法找到所选类型对应的 ID。", "错误", WinForms.MessageBoxButtons.OK, WinForms.MessageBoxIcon.Error);
                    this.DialogResult = WinForms.DialogResult.None;
                }
            }
            else
            {
                WinForms.MessageBox.Show("请先选择一个空间类型。", "提示", WinForms.MessageBoxButtons.OK, WinForms.MessageBoxIcon.Warning);
                this.DialogResult = WinForms.DialogResult.None;
            }
        }
    }
}